// @Author EthanScriptOn
// @Date 2023/11/29 17:48:00
// @Desc
package core

import (
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"sync"
	"sync/atomic"
	"time"
)

type SrfSwitchContext struct {
	mu   sync.RWMutex
	done atomic.Value
	err  error
	keys map[interface{}]interface{}
}

func (s *SrfSwitchContext) Set(key interface{}, value interface{}) {
	_ = util.LockWithAsync(s.mu.Lock, s.mu.Unlock, func() (err error) {
		if s.keys == nil {
			s.keys = make(map[interface{}]interface{})
		}
		s.keys[key] = value
		return
	})
}

func (s *SrfSwitchContext) Get(key interface{}) (value interface{}, exists bool) {
	_ = util.LockWithAsync(s.mu.RLock, s.mu.RUnlock, func() (err error) {
		value, exists = s.keys[key]
		return
	})
	return
}

func (s *SrfSwitchContext) Deadline() (deadline time.Time, ok bool) {
	return
}

func (s *SrfSwitchContext) Done() <-chan struct{} {
	d := s.done.Load()
	if d != nil {
		return d.(chan struct{})
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	d = s.done.Load()
	if d == nil {
		d = make(chan struct{})
		s.done.Store(d)
	}
	return d.(chan struct{})
}

func (s *SrfSwitchContext) Err() error {
	s.mu.Lock()
	err := s.err
	s.mu.Unlock()
	return err
}

func (s *SrfSwitchContext) Value(key interface{}) interface{} {
	value, _ := s.Get(key)
	return value
}
